#define FFI_LIB "libxxhash.so"

typedef enum { XXH_OK=0, XXH_ERROR } XXH_errorcode;

typedef uint32_t XXH32_hash_t;
typedef uint64_t XXH64_hash_t;

struct XXH3_state_s {
   XXH64_hash_t acc[8];
   unsigned char customSecret[192];  /* used to store a custom secret generated from the seed. Makes state larger. Design might change */
   unsigned char buffer[256];
   XXH32_hash_t bufferedSize;
   XXH32_hash_t nbStripesPerBlock;
   XXH32_hash_t nbStripesSoFar;
   XXH32_hash_t secretLimit;
   XXH32_hash_t reserved32;
   XXH32_hash_t reserved32_2;
   XXH64_hash_t totalLen;
   XXH64_hash_t seed;
   XXH64_hash_t reserved64;
   const unsigned char* secret;    /* note : there is some padding after, due to alignment on 64 bytes */
};   /* typedef'd to XXH3_state_t */

typedef struct XXH3_state_s XXH3_state_t;

extern XXH3_state_t* XXH3_createState(void);
extern XXH_errorcode XXH3_freeState(XXH3_state_t* statePtr);

typedef struct {
    XXH64_hash_t low64;
    XXH64_hash_t high64;
} XXH128_hash_t;

extern XXH128_hash_t XXH128(const void* data, size_t len, XXH64_hash_t seed);
extern XXH128_hash_t XXH3_128bits(const void* data, size_t len);
extern XXH128_hash_t XXH3_128bits_withSeed(const void* data, size_t len, XXH64_hash_t seed);  /* == XXH128() */
extern XXH128_hash_t XXH3_128bits_withSecret(const void* data, size_t len, const void* secret, size_t secretSize);

extern XXH_errorcode XXH3_128bits_reset(XXH3_state_t* statePtr);
extern XXH_errorcode XXH3_128bits_reset_withSeed(XXH3_state_t* statePtr, XXH64_hash_t seed);
extern XXH_errorcode XXH3_128bits_reset_withSecret(XXH3_state_t* statePtr, const void* secret, size_t secretSize);

extern XXH_errorcode XXH3_128bits_update (XXH3_state_t* statePtr, const void* input, size_t length);
extern XXH128_hash_t XXH3_128bits_digest (const XXH3_state_t* statePtr);

typedef struct { unsigned char digest[16]; } XXH128_canonical_t;
extern void XXH128_canonicalFromHash(XXH128_canonical_t* dst, XXH128_hash_t hash);
extern XXH128_hash_t XXH128_hashFromCanonical(const XXH128_canonical_t* src);
